using System;
using System.Collections.Generic;
using System.Linq;

namespace ExcelTemplateEngine.Models.TemplateModels
{
    /// <summary>
    /// 模板单元格节点 - 三树模型中的"意图层"核心数据结构
    /// </summary>
    public class TemplateCellNode
    {
        #region 基本信息
        
        /// <summary>
        /// 单元格地址，如"A1"
        /// </summary>
        public string? Address { get; set; }
        
        /// <summary>
        /// 单元格原始值（可能包含模板标记）
        /// </summary>
        public string? RawValue { get; set; }
        
        /// <summary>
        /// 模板表达式，如"{{ds.Name}}"，如果不是模板则为null
        /// </summary>
        public string? Expression { get; set; }
        
        /// <summary>
        /// 节点的唯一标识符
        /// </summary>
        public string NodeId { get; set; }
        
        #endregion
        
        #region 扩展属性
        
        /// <summary>
        /// 扩展类型
        /// </summary>
        public ExpansionType ExpansionType { get; set; } = ExpansionType.None;
        
        /// <summary>
        /// 扩展方向
        /// </summary>
        public ExpansionDirection ExpansionDirection { get; set; } = ExpansionDirection.Vertical;
        
        #endregion
        
        #region 多重父节点关系（支持交叉扩展的核心设计）
        
        /// <summary>
        /// 垂直扩展的上级单元格
        /// </summary>
        public TemplateCellNode? UpperParent { get; set; }
        
        /// <summary>
        /// 水平扩展的左级单元格
        /// </summary>
        public TemplateCellNode? LeftParent { get; set; }
        
        /// <summary>
        /// 树结构中的逻辑父节点
        /// </summary>
        public TemplateCellNode? Parent { get; set; }
        
        /// <summary>
        /// 子节点列表
        /// </summary>
        public List<TemplateCellNode> Children { get; set; }
        
        #endregion
        
        #region 样式和属性
        
        /// <summary>
        /// 完整样式信息
        /// </summary>
        public FullCellStyle? Style { get; set; }
        
        /// <summary>
        /// 模板属性（如 Context、Sort、Filter 等）
        /// </summary>
        public Dictionary<string, object> Properties { get; set; }
        
        #endregion
        
        #region 数据绑定
        
        /// <summary>
        /// 是否为数据绑定单元格
        /// </summary>
        public bool IsDataBindingCell { get; set; }
        
        /// <summary>
        /// 数据源路径，如"ds"
        /// </summary>
        public string? DataSourcePath { get; set; }
        
        /// <summary>
        /// 字段名称，如"Name"
        /// </summary>
        public string? FieldName { get; set; }
        
        /// <summary>
        /// 单元格引用列表（公式中引用的其他单元格）
        /// </summary>
        public List<string> CellReferences { get; set; }
        
        #endregion
        
        #region 循环依赖检测
        
        /// <summary>
        /// 用于检测循环依赖的访问节点集合
        /// </summary>
        public HashSet<string> VisitedNodes { get; set; }
        
        /// <summary>
        /// 处理状态标记
        /// </summary>
        public bool IsProcessing { get; set; }
        
        #endregion
        
        #region 构造函数
        
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public TemplateCellNode()
        {
            NodeId = Guid.NewGuid().ToString();
            Children = new List<TemplateCellNode>();
            Properties = new Dictionary<string, object>();
            CellReferences = new List<string>();
            VisitedNodes = new HashSet<string>();
            Style = new FullCellStyle();
        }
        
        /// <summary>
        /// 带地址的构造函数
        /// </summary>
        /// <param name="address">单元格地址</param>
        public TemplateCellNode(string address) : this()
        {
            Address = address;
        }
        
        #endregion
        
        #region 公共方法
        
        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="child">子节点</param>
        public void AddChild(TemplateCellNode child)
        {
            if (child == null)
                throw new ArgumentNullException(nameof(child));
                
            if (child == this)
                throw new InvalidOperationException("节点不能作为自己的子节点");
                
            Children.Add(child);
            child.Parent = this;
        }
        
        /// <summary>
        /// 移除子节点
        /// </summary>
        /// <param name="child">子节点</param>
        public bool RemoveChild(TemplateCellNode child)
        {
            if (child == null)
                return false;
                
            if (Children.Remove(child))
            {
                child.Parent = null;
                return true;
            }
            
            return false;
        }
        
        /// <summary>
        /// 获取所有祖先节点
        /// </summary>
        public IEnumerable<TemplateCellNode> GetAncestors()
        {
            var current = Parent;
            while (current != null)
            {
                yield return current;
                current = current.Parent;
            }
        }
        
        /// <summary>
        /// 获取所有后代节点
        /// </summary>
        public IEnumerable<TemplateCellNode> GetDescendants()
        {
            foreach (var child in Children)
            {
                yield return child;
                foreach (var descendant in child.GetDescendants())
                {
                    yield return descendant;
                }
            }
        }
        
        /// <summary>
        /// 判断是否为叶子节点
        /// </summary>
        public bool IsLeaf => !Children.Any();
        
        /// <summary>
        /// 判断是否为根节点
        /// </summary>
        public bool IsRoot => Parent == null;
        
        /// <summary>
        /// 获取节点深度
        /// </summary>
        public int GetDepth()
        {
            return GetAncestors().Count();
        }
        
        /// <summary>
        /// 克隆节点（浅拷贝）
        /// </summary>
        public TemplateCellNode Clone()
        {
            return new TemplateCellNode
            {
                Address = Address,
                RawValue = RawValue,
                Expression = Expression,
                NodeId = NodeId,
                ExpansionType = ExpansionType,
                ExpansionDirection = ExpansionDirection,
                IsDataBindingCell = IsDataBindingCell,
                DataSourcePath = DataSourcePath,
                FieldName = FieldName,
                Style = Style?.Clone(),
                Properties = new Dictionary<string, object>(Properties),
                CellReferences = new List<string>(CellReferences)
            };
        }
        
        /// <summary>
        /// 获取调试信息
        /// </summary>
        public override string ToString()
        {
            var info = $"TemplateCellNode[{Address}]";
            if (!string.IsNullOrEmpty(Expression))
            {
                info += $" Expression={Expression}";
            }
            if (IsDataBindingCell)
            {
                info += $" DataBinding={DataSourcePath}.{FieldName}";
            }
            return info;
        }
        
        #endregion
    }
}